package com.habitsoft.glassfish.dashboard.server;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.security.DeclareRoles;

import org.apache.commons.lang.StringUtils;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.habitsoft.glassfish.dashboard.client.AccessDenied;
import com.habitsoft.glassfish.dashboard.client.LogNotFound;
import com.habitsoft.glassfish.dashboard.client.LogService;

@DeclareRoles("log-service")
public class LogServiceImpl extends RemoteServiceServlet implements LogService {
    private static final long serialVersionUID = 4983880032596558687L;
    
    @Override
    public String[] listLogFiles() throws AccessDenied {
        File dir = getLogsDir();
        if (dir.isDirectory()) {
            return dir.list(new FilenameFilter() {
                @Override
                public boolean accept(File dir, String name) {
                    return name.toLowerCase().contains(".log");
                }
            });
        }
        try {
            log("Unable to determine path to log files.  CWD is " + new File(".").getCanonicalPath());
        } catch (IOException e) {
            log("Unable to print current directory", e);
        }
        return new String[0];
    }

    private File getLogsDir() {
        File dir = new File("../logs");
        return dir;
    }

    LogFilter parseFilter(String filter) {
        if(StringUtils.isEmpty(filter))
            return NullFilter.instance;
        return new RegexFilter(filter);
    }
    
    @Override
    public int countLogMessages(String logFileName, String filter) throws LogNotFound, AccessDenied {
        LogFileIterator iter = openLog(logFileName, filter);
        int count=0;
        while(iter.hasNext()) {
            iter.next();
            count++;
        }
        return count;
    }

    private File getLogFile(String logFileName) throws LogNotFound {
        if(StringUtils.isEmpty(logFileName))
            throw new LogNotFound();
        File dir = getLogsDir();
        File logFile = new File(dir, logFileName);
        return logFile;
    }

    @Override
    public String[] getLogMessages(String logFileName, String filter, int offset, int limit) throws AccessDenied, LogNotFound {
        LogFileIterator iter = openLog(logFileName, filter);
        for(int i=0; i < offset && iter.hasNext(); i++) {
            iter.next();
        }
        List<String> results = new ArrayList<String>(limit);
        for(int i=0; i < limit && iter.hasNext(); i++) {
            results.add(iter.next());
        }
        return results.toArray(new String[results.size()]);
    }

    private LogFileIterator openLog(String logFileName, String filter) throws LogNotFound {
        LogFileIterator iter;
        try {
            iter = new LogFileIterator(getLogFile(logFileName), parseFilter(filter));
        } catch (FileNotFoundException e) {
            throw new LogNotFound();
        }
        return iter;
    }
}
